﻿using KongMing.ORM.EFCore.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;

namespace KongMing.ORM.EFCore
{
    public class 多线程操作
    {
        public static void Go()
        {
            //AddProjects().Wait();
            //TestAsyncDemo();
            DoTaskDemoAsync();
            Console.WriteLine("主线程结束，不等待");
            Thread.Sleep(2000);
        }


        public async static Task AddProjects()
        {
            var projects = new ConcurrentBag<Project>();
            Random random = new Random();
            var cts = new CancellationTokenSource();
            using (var db = new EFDBContext())
            {
                try
                {
                    db.Database.BeginTransaction();
                    Parallel.For(1, 21, new ParallelOptions { CancellationToken = cts.Token, MaxDegreeOfParallelism = 2 }, i =>
                        {
                            try
                            {
                                Console.WriteLine($"线程id:{Thread.CurrentThread.ManagedThreadId}，i等于：{i}，正常开始运行...");
                                if (i == 5 || i == 6)
                                {
                                    throw new Exception($"id等于{i}，抛异常");
                                }
                                var project = new Project
                                {
                                    ProjectId = i,
                                    ProjectName = $"项目 {i} ",
                                    ProjectType = random.Next(0, 3),
                                    Status = 0,
                                    Sort = i
                                };
                                projects.Add(project);
                                Console.WriteLine($"线程id:{Thread.CurrentThread.ManagedThreadId}，i等于：{i}，正常结束...");
                            }
                            catch (Exception)
                            {
                                cts.Cancel();
                                throw;
                            }
                        });
                    db.Project.AddRange(projects);
                    int res = await db.SaveChangesAsync();
                    db.Database.CommitTransaction();
                }
                catch (Exception ex)
                {
                    var aex = (AggregateException)ex;
                    StringBuilder stringBuilder = new StringBuilder("异常信息：");
                    foreach (var item in aex.InnerExceptions)
                    {
                        stringBuilder.AppendLine(item.Message);
                    }
                    Console.WriteLine(stringBuilder.ToString());
                    db.Database.RollbackTransaction();
                    throw ex;
                }
            }
        }


        public static void TestAsyncDemo()
        {
            List<int> list1 = new List<int>();
            ConcurrentBag<int> list2 = new ConcurrentBag<int>();
            int count = 0;
            var cts = new CancellationTokenSource();
            cts.Token.Register(() =>
            {
                Console.WriteLine($"线程id：{Thread.CurrentThread.ManagedThreadId} 被取消！");
            });
            try
            {
                for (int i = 1; i <= 20; i++)
                {
                    int j = i;
                    Task.Run(() =>
                    {
                        try
                        {
                            Console.WriteLine($" 序号：{j} 线程id:{Thread.CurrentThread.ManagedThreadId}，开始运行...");
                            count++;
                            Thread.Sleep(new Random().Next(300, 700));
                            if (j == 6 || j == 8)
                                throw new Exception($"j={j}，抛异常！");
                            if (!cts.IsCancellationRequested)
                            {
                                Console.WriteLine($" 序号：{j} 线程id:{Thread.CurrentThread.ManagedThreadId}，正常结束...");
                                list1.Add(j);
                                list2.Add(j);
                            }
                            else
                                Console.WriteLine($" 序号：{j} 线程id:{Thread.CurrentThread.ManagedThreadId}，收到异常通知，但是没法取消，结束...");

                        }
                        catch (Exception ex)
                        {
                            cts.Cancel();
                            throw ex;
                        }
                    }, cts.Token);
                }
                Thread.Sleep(10000);
            }
            catch (Exception ex)
            {
                var aex = (AggregateException)ex;
                StringBuilder stringBuilder = new StringBuilder().AppendLine("异常信息：");
                foreach (var item in aex.InnerExceptions)
                {
                    stringBuilder.AppendLine(item.Message);
                }
                Console.WriteLine(stringBuilder.ToString());
            }
            Console.WriteLine();
        }


        public static void TestSafetyDemo()
        {

        }

        public async static Task DoTaskDemoAsync()
        {
            
            List<int> list = new List<int>();
            for (int i = 0; i < 200; i++)
            {
                await Task.Delay(new Random().Next(20,300));
                Console.WriteLine(i);
                list.Add(i);
            }
            Console.WriteLine("子线程执行完成");
        }
    }
}
